﻿namespace EasyToolkit.Excel.Application.Async
{
    using System;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Windows.Threading;
    using EasyToolkit.Tools.Log;

    class ExcelAsyncExecution : NativeWindow, IDisposable
    {
        #region attributes and properties
        public Dispatcher ExcelDispatcher
        { get; private set; }
        private object syncObj = new object();
        #endregion

        #region .ctors
        public ExcelAsyncExecution(ExcelApplication application)
        {
            ExcelDispatcher = Dispatcher.CurrentDispatcher;
        }
        #endregion

        #region public methods
        public void PostUpdate(System.Action action)
        {
            if (ExcelDispatcher != null)
                ExcelDispatcher.BeginInvoke(new Action(() => ExecuteAction(action)));
        }

        public void Dispose()
        {
            ExcelDispatcher = null;
        }
        #endregion

        #region private methods
        private void ExecuteAction(Action action)
        {
            try
            {
                action();
            }
            catch (COMException)
            {
                Task task = new Task(() => { 
                                                Thread.Sleep(25);
                                                ExecuteAction(action);
                                           });
                task.Start();
            }
            catch (Exception ex)
            {
                string message = string.Format("'ExcelAsyncWindow.ExecuteAction' failed.{0}", ex.Message);
                Logger.Instance.LogException(LogType.Error, ex, message);
            }
        }
        #endregion
    }
}